﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;

namespace Client
{
    public partial class MainForm : System.Windows.Forms.Form
    {
        // 유저정보
        //public static UserData userData = new UserData();
        public static CCL.TableStructure.User userData = null;
        public static List<CCL.TableStructure.Project> projList = null;
        public static List<List<CCL.TableStructure.ProjectMember>> projectMemberList = null;

        public static Connector connector = new Connector();

        public MainForm()
        {
            InitializeComponent();

            /*
            // Connect Server
            if (Connector.ConnectServer() == false)
            {
                // 서버 접속에 실패했을 경우
                // MessageBox 로 Error Message 출력 후, 프로그램 종료
                MessageBox.Show("서버 접속에 실패했습니다.");
                this.Close();
            }
              */

            RegistryAdmin.Init();
            CheckLoginState();
            TxtReader.CreateSystemFile();
        }


        public static void GetDirectoryNodes(TreeNode rootNode, DirectoryInfo dir)
        {
            DirectoryInfo[] directories = dir.GetDirectories();

            foreach (DirectoryInfo subdir in directories)
            {
                TreeNode dirnode = new TreeNode(subdir.Name);
                rootNode.Nodes.Add(dirnode);
                GetDirectoryNodes(dirnode, subdir);
            }
        }

        public static void GetDirectoryNodes(TreeNode rootNode, DirectoryInfo dir, bool CallAgain)
        {
            DirectoryInfo[] directories = dir.GetDirectories();

            foreach (DirectoryInfo subdir in directories)
            {
                TreeNode dirnode = new TreeNode(subdir.Name);

                try
                {
                    FileInfo[] fi = subdir.GetFiles();
                    foreach (FileInfo file in fi)
                    {
                        if (file.FullName == subdir.FullName + "\\test.txt")
                        {
                            dirnode.ImageIndex = 1;
                            break;
                        }
                    }

                    rootNode.Nodes.Add(dirnode);


                    if (CallAgain == true)
                    {
                        MainForm.GetDirectoryNodes(dirnode, subdir, false);
                    }
                }
                catch (System.Exception ex)
                {

                }
            }
        }

        // 해당 노드의 절대경로를 반환
        public static string GetFullPathName(TreeNode node)
        {
            if (node.Parent == null)
            {
                return node.Text;
            }
            else
            {
                return GetFullPathName(node.Parent) + node.Text + "\\";
            }
        }

        public static void InitiateTree(TreeView DirTree)
        {
            // Tree 초기상태는 Drive 만 화면에 출력시킴.
            DriveInfo[] allDrives = DriveInfo.GetDrives();

            foreach (DriveInfo drive in allDrives)
            {
                // 준비된 드라이버만 화면에 표시 
                // ex) C:\, D:\
                if (drive.IsReady == true)
                {
                    DirectoryInfo dir = new DirectoryInfo(drive.Name);

                    TreeNode root = new TreeNode(drive.Name);
                    DirTree.Nodes.Add(root);
                    MainForm.GetDirectoryNodes(root, dir, true);
                }
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // Directory Tree View Initialize
            InitiateTree(DirTreeView);
        }

        private void DirTreeView_AfterExpand(object sender, TreeViewEventArgs e)
        {
            DirectoryInfo dir = new DirectoryInfo(GetFullPathName(e.Node));
            e.Node.Nodes.Clear();
            GetDirectoryNodes(e.Node, dir, true);
        }

        private void DirTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            txtFullPath.Text = GetFullPathName(e.Node);

            // 해당폴더가 관리중인 프로젝트인지 확인
            // 임의의 파일이 존재하는가 확인.
            try
            {
                string[] files = Directory.GetFiles(txtFullPath.Text);
                foreach (string file in files)
                {
                    if (file == (txtFullPath.Text + "test.txt"))
                    {
                        // 파일이 존재할 경우
                        // 모든 버튼들을 활성화
                        btnCommit.Enabled = true;
                        btnUpdate.Enabled = true;
                        btnAdmin.Enabled = true;
                        btnCheckOut.Enabled = false;
                        btnCreate.Enabled = false;

                        TxtReader.ReadDataFile(txtFullPath.Text);
                        string projectID = TxtReader.GetString(TxtReader.LINE.PROJECTID);

                        CCL.TableStructure.Project pInfo = GetProjectInfo(Int32.Parse(projectID));
                        // 프로젝트 정보를 화면에 출력
                        if (pInfo == null)
                        {
                            lbProjectName.Text = "프로젝트 : 접근 불가능";
                            lbProjectPath.Text = "폴더경로 : " + txtFullPath.Text;                            
                        }
                        else
                        {
                            lbProjectName.Text = "프로젝트 : " + CCL.Utility.StringUtility.ConvertToStr(pInfo.ProjectName);
                            lbProjectPath.Text = "폴더경로 : " + txtFullPath.Text;
                        }
                        
                        return;
                    }
                }
                // 파일이 존재하지 않을경우
                // 해당폴더가 관리중인 폴더가 아님.
                // 모든 버튼들을 비활성화
                btnCommit.Enabled = false;
                btnUpdate.Enabled = false;
                btnAdmin.Enabled = false;
                btnCheckOut.Enabled = true;
                btnCreate.Enabled = true;

                // 폴더 정보를 화면에 출력
                lbFolderPath.Text = "경로 : " + txtFullPath.Text;
            }
            catch (System.IO.IOException ex)
            {
                // 여기도 예외따위
                // 우걱우걱
            }
        }

        // 로그인 상태를 확인하고
        // 로그아웃 상태일경우 LoginForm 을 실행
        public void CheckLoginState()
        {
            ctrlUserInfo.Controls.Clear();

            if (userData == null)
            {
                LoginControl control = new LoginControl(this);
                ctrlUserInfo.Controls.Add(control);
                /*
                LoginForm form = new LoginForm();
                if (form.ShowDialog() == DialogResult.Yes)
                {
                    LoginMenuItem.Enabled = false;
                    LogoutMenuItem.Enabled = true;

                }*/
                if (customTabControl1.Controls.Contains(tabProject) == true)
                {
                    customTabControl1.Controls.Remove(tabProject);
                }
                
            }
            else
            {

                UserInfoControl control = new UserInfoControl(this, CCL.Utility.StringUtility.ConvertToStr(userData.Email), CCL.Utility.StringUtility.ConvertToStr(userData.Name));
                ctrlUserInfo.Controls.Add(control);

                if (customTabControl1.Controls.Contains(tabProject) == false)
                {
                    customTabControl1.Controls.Add(tabProject);
                }
                
            }
        }

        // 버튼 타입
        enum BTN_TYPE
        {
            CHECKOUT,
            COMMIT,
            UPDATE,
            ADMIN,
            CREATE
        }

        public void ChangeLoginMenu(bool isLogin) 
        {
            LoginMenuItem.Enabled = !isLogin;
            LogoutMenuItem.Enabled = isLogin;
        }

        public void ClearUserData()
        {
            userData = null;
        }

        // 클릭한 버튼의 타입에 따라 폼을 실행
        // Factory 
        private void BtnClickEvent(BTN_TYPE type)
        {
            if (userData == null)
            {
                LoginForm form = new LoginForm();
                form.ShowDialog();
                
            }
            if (userData != null)
            {
                LoginMenuItem.Enabled = false;
                LogoutMenuItem.Enabled = true;
            }
            CheckLoginState();
            if (userData != null)
            {
                System.Windows.Forms.Form form = new System.Windows.Forms.Form();
                switch (type)
                {
                    case BTN_TYPE.CHECKOUT:
                        form = new CheckOutForm(txtFullPath.Text);
                        break;
                    case BTN_TYPE.COMMIT:
                        form = new CommitForm(txtFullPath.Text);
                        break;
                    case BTN_TYPE.ADMIN:
                        // 관리하기 버튼은 관리자에게만 허용
                        TxtReader.ReadDataFile(txtFullPath.Text);
                        int projectID = Int32.Parse(TxtReader.GetString(TxtReader.LINE.PROJECTID));
                        CCL.TableStructure.Project pInfo = GetProjectInfo(projectID);
                        if (pInfo == null || pInfo.ProjectOwner.UserID != userData.UserID)
                        {
                            MessageBox.Show("프로젝트 관리자만 사용할 수 있습니다.");
                            return;
                        }
                        else
                        {
                            form = new AdminForm(this, projectID);
                            break;
                        }
                    case BTN_TYPE.UPDATE:
                        form = new UpdateForm(txtFullPath.Text);
                        break;
                    case BTN_TYPE.CREATE:
                        form = new CreateProjectForm(txtFullPath.Text);
                        break;
                }

                form.Show();
            }
        }

        private void btnCheckOut_Click(object sender, EventArgs e)
        {
            BtnClickEvent(BTN_TYPE.CHECKOUT);
        }

        private void btnCommit_Click(object sender, EventArgs e)
        {
            BtnClickEvent(BTN_TYPE.COMMIT);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            BtnClickEvent(BTN_TYPE.UPDATE);
        }

        private void btnAdmin_Click(object sender, EventArgs e)
        {
                BtnClickEvent(BTN_TYPE.ADMIN);
        }

        private void btnCreate_Click(object sender, EventArgs e)
        {
            BtnClickEvent(BTN_TYPE.CREATE);
        }

        // 단일한 로그인 폼 실행
        private void LoginMenuItem_Click(object sender, EventArgs e)
        {
            //CheckLoginState();
            LoginForm form = new LoginForm();
            form.Show();
            
            if (userData != null)
            {
                LoginMenuItem.Enabled = false;
                LogoutMenuItem.Enabled = true;
            }
            CheckLoginState();
        }



        private void JoinMenuItem_Click(object sender, EventArgs e)
        {
            CreateAccountForm form = new CreateAccountForm();
            form.Show();
        }

        private void LogoutMenuItem_Click(object sender, EventArgs e)
        {
            toolStripLbID.Text = "";
            userData = null;
            LoginMenuItem.Enabled = true;
            LogoutMenuItem.Enabled = false;

            CheckLoginState();
        }

        // 강제종료 이벤트
        private void ExitMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        // 강제종료 이벤트
        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            notifyIcon.Visible = false;
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason != CloseReason.ApplicationExitCall)
            {
                e.Cancel = true;
                this.Visible = false;
                notifyIcon.Visible = true;
            }
        }

        private void notifyIcon_Click(object sender, EventArgs e)
        {
            contextMenuStrip.Show();
        }

        private void logOutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripLbID.Text = "";
            userData = null;
            projList = null;
            LoginMenuItem.Enabled = true;
            LogoutMenuItem.Enabled = false;
            CheckLoginState();
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            notifyIcon.Visible = false;
        }

        private void optionMenuItem_Click(object sender, EventArgs e)
        {
            OptionForm form = new OptionForm();
            form.Show();
        }

        // 자동 로그인 상태인지 확인
        private void CheckAutoLogin()
        {
            bool isLogin = (bool)RegistryAdmin.GetRegistryKey(RegistryAdmin.KEY_NAME.SAVE_ID);
            
            // 자동로그인 상태일 경우
            if (isLogin == true)
            {
                // 레지스트리로부터 아이디와 패스워드를 가져옴.
                string id = (string)RegistryAdmin.GetRegistryKey(RegistryAdmin.KEY_NAME.ID);
                string pswd = (string)RegistryAdmin.GetRegistryKey(RegistryAdmin.KEY_NAME.PASSWORD);

                // 송신
                CCL.SocketMessage.Request.Login packet = new CCL.SocketMessage.Request.Login(id, pswd);
                CCL.SocketMessage.Message message = CCL.SocketMessage.Message.MessageRequestBuilder(packet);
                byte[] msg = message.GetByte();

                CCL.SocketMessage.Message loginMsg = MainForm.connector.Execute(msg);
                CCL.SocketMessage.Response.Login loginResponse = (CCL.SocketMessage.Response.Login)loginMsg.Body;

                // 로그인 확인
                if (loginResponse.Result == CCL.SocketMessage.Constant.Result.Success)
                {
                    // 유저정보를 입력함.
                    MainForm.userData = loginResponse.UserInfo;

                    // 유저의 프로젝트 리스트를 서버로부터 받아옴.
                    CCL.SocketMessage.Request.GetProjectList reqPacket = new CCL.SocketMessage.Request.GetProjectList(MainForm.userData.UserID);
                    CCL.SocketMessage.Message plMessage = CCL.SocketMessage.Message.MessageRequestBuilder(reqPacket);
                    CCL.SocketMessage.Message reqMsg = MainForm.connector.Execute(plMessage.GetByte());
                    CCL.SocketMessage.Response.GetProjectList plResponse = (CCL.SocketMessage.Response.GetProjectList)reqMsg.Body;
                    
                    // 프로젝트를 정상적으로 가져왔을 경우
                    if (plResponse.Result == CCL.SocketMessage.Constant.Result.Success)
                    {
                        MainForm.projList = plResponse.ProjectList;

                        // 프로젝트 멤버리스트도 가져와야지..ㅋㅋ
                        //SetMemberList();
                    }

                    // 로그인 상태로 변경
                    toolStripLbID.Text = id;
                    LoginMenuItem.Enabled = false;
                    LogoutMenuItem.Enabled = true;
                }
                else
                {
                    MessageBox.Show(CCL.Utility.StringUtility.ConvertToStr(loginResponse.ErrorMessage));
                }
            }
        }

        private void HelpMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("아직 공사중입니다.");
        }

        // Project List View 초기화
        private void InitProjectListView()
        {
            // Project List View 데이터를 모두 지움.
            projectListView.Items.Clear();
            if (projList != null)
            {
                foreach (CCL.TableStructure.Project project in projList)
                {
                    //string adr = TxtReader.FindPathForProject(project.ProjectID.ToString());
                    //if (adr != null)
                    //{
                   //   TxtReader.ReadDataFile(adr);
                        string value = CCL.Utility.StringUtility.ConvertToStr(project.ProjectName);
                        
                        ListViewItem item = new ListViewItem(value);
                        projectListView.Items.Add(item);
                    //}
                    //else
                    //{
                    //    string value = CCL.Utility.StringUtility.ConvertToStr(project.ProjectName);
                     //   ListViewItem item = new ListViewItem(value);
                       // projectListView.Items.Add(item);
                    //}
                }
            }
        }

        // Project List View 새로고침
        private void GetProjectListFromServer()
        {
            // 프로젝트 리스트를 서버로부터 가져옴.
            CCL.SocketMessage.Request.GetProjectList reqPacket = new CCL.SocketMessage.Request.GetProjectList(MainForm.userData.UserID);
            CCL.SocketMessage.Message plMessage = CCL.SocketMessage.Message.MessageRequestBuilder(reqPacket);
            CCL.SocketMessage.Message reqMsg = MainForm.connector.Execute(plMessage.GetByte());
            CCL.SocketMessage.Response.GetProjectList plResponse = (CCL.SocketMessage.Response.GetProjectList)reqMsg.Body;
            if (plResponse.Result == CCL.SocketMessage.Constant.Result.Success)
            {
                MainForm.projList = plResponse.ProjectList;
                SetMemberList();
            }
            else
            {
                MainForm.projList = null;
            }

            // List View 를 새로고침.
            InitProjectListView();
        }

        private void 프로젝트ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (userData == null)
            {
                LoginForm logForm = new LoginForm();
                logForm.ShowDialog();

                
            }

            if (userData != null)
            {
                CheckLoginState();
                ChangeLoginMenu(true);
            }

            if (userData != null)
            {
                CreateProjectForm form = new CreateProjectForm();
                form.Show();
            }

            
        }

        // 메인탭 - 프로젝트 체크 버튼을 변경하였을때
        private void ProjectMenuItem_CheckStateChanged(object sender, EventArgs e)
        {
            if (ProjectMenuItem.CheckState == CheckState.Checked)
            {
                this.customTabControl1.Controls.Add(this.tabProject);
            }
            else if (ProjectMenuItem.CheckState == CheckState.Unchecked)
            {
                this.customTabControl1.Controls.Remove(this.tabProject);
            }
        }

        // 메인탭 - 폴더탭의 체크 버튼을 변경하였을때
        private void FolderMenuItem_CheckStateChanged(object sender, EventArgs e)
        {
            if (FolderMenuItem.CheckState == CheckState.Checked)
            {
                this.customTabControl1.Controls.Add(this.tabFolder);
            }
            else if (FolderMenuItem.CheckState == CheckState.Unchecked)
            {
                this.customTabControl1.Controls.Remove(this.tabFolder);
            }
        }

        // 메인 폼의 탭 페이지를 닫을때 발생하는 이벤트
        private void customTabControl1_TabClosing(object sender, TabControlCancelEventArgs e)
        {
            if (e.TabPageIndex == 0)
            {
                e.Cancel = true;
            }
            if (e.TabPage == this.tabFolder)
            {
                this.customTabControl1.Controls.Remove(this.tabFolder);
                FolderMenuItem.CheckState = CheckState.Unchecked;
                e.Cancel = true;
            }
            if (e.TabPage == this.tabProject)
            {
                this.customTabControl1.Controls.Remove(this.tabProject);
                ProjectMenuItem.CheckState = CheckState.Unchecked;
                e.Cancel = true;
            }
        }

        // 관리하기 - 로그탭의 체크 버튼을 해제
        public void ChangeLogMenuItem()
        {
            LogMenuItem.CheckState = CheckState.Unchecked;
        }

        // 관리하기- 로그탭의 체브상태를 반환
        public CheckState GetLogMenuItem()
        {
            return LogMenuItem.CheckState;
        }

        private void customTabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (e.TabPage == tabProject)
            {
                GetProjectListFromServer();
            }
        }

        private void projectListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (e.IsSelected == true)
            {
                CCL.TableStructure.Project project = projList[e.ItemIndex];
                string adr = TxtReader.FindPathForProject(project.ProjectID.ToString());

                if (adr != null)
                {
                    TxtReader.ReadDataFile(adr);
                    lbProjPath.Text = "경로 : " + adr;
                    lbVersion.Text = "현재 버젼 : " + TxtReader.GetString(TxtReader.LINE.VERSION);
                }
                else
                {
                    lbProjPath.Text = "경로 : 프로젝트 설치되지 않음";
                    lbVersion.Text = "현재 버젼 : 버전 없음";
                }

                lbProjName.Text = "프로젝트 명 " + CCL.Utility.StringUtility.ConvertToStr(project.ProjectName);
                lbNewVersion.Text = "최근 버젼 : " + project.HeadRevision.ToString();
                lbAdminID.Text = "관리자 : " + CCL.Utility.StringUtility.ConvertToStr(project.ProjectOwner.Email) + " (" + CCL.Utility.StringUtility.ConvertToStr(project.ProjectOwner.Name) + ")";

                memberList.Items.Clear();
                List<CCL.TableStructure.ProjectMember> listMember = projectMemberList[e.ItemIndex];
                foreach (CCL.TableStructure.ProjectMember member in listMember)
                {
                    memberList.Items.Add(CCL.Utility.StringUtility.ConvertToStr(member.UserInfo.Email) + " (" + CCL.Utility.StringUtility.ConvertToStr(member.UserInfo.Name) + ")");
                }
                
            }
        }

        public void SetMemberList()
        {
            if (projectMemberList != null)
            {
                projectMemberList.Clear();
                
            }
            else
            {
                projectMemberList = new List<List<CCL.TableStructure.ProjectMember>>();
            }
            
            foreach(CCL.TableStructure.Project project in projList)
            {
                CCL.SocketMessage.Request.GetProjectMemberList reqPacket = new CCL.SocketMessage.Request.GetProjectMemberList(project.ProjectID);
                CCL.SocketMessage.Message plMessage = CCL.SocketMessage.Message.MessageRequestBuilder(reqPacket);
                CCL.SocketMessage.Message reqMsg = MainForm.connector.Execute(plMessage.GetByte());

                CCL.SocketMessage.Response.GetProjectMemberList plResponse = (CCL.SocketMessage.Response.GetProjectMemberList)reqMsg.Body;
                if (plResponse.Result == CCL.SocketMessage.Constant.Result.Success)
                {
                    projectMemberList.Add(plResponse.ProjectMemberList);
                }
                else
                {
                    if (projectMemberList != null)
                    {
                        projectMemberList.Clear();
                    }
                   
                    MessageBox.Show(CCL.Utility.StringUtility.ConvertToStr(plResponse.ErrorMessage));
                    return;
                }
            }
        }

        public static CCL.TableStructure.Project GetProjectInfo(int projID)
        {
            foreach (CCL.TableStructure.Project project in projList)
            {
                if (projID == project.ProjectID)
                {
                    return project;
                }
            }
            return null;
        }
    }
}
